import java.util.zip.ZipEntry;

class Food {
}

class Meat extends Food {
}

class Pork extends Meat {
}

class Beef extends Meat {
}

class Fruit extends Food {
}

class Apple extends Fruit {
}

class Banana extends Fruit {
}

class GreenApple extends Apple {
}

class RedApple extends Apple {
}

// 盘子-泛型类型
class Plate<T> {
    private T item;
    public Plate(T t) {
        item = t;
    }
    public Plate() {
    }
    public void setItem(T item) {
        this.item = item;
    }
    public T getItem() {
        return item;
    }
}

public class Test {
    public static void main(String[] args) {
        // 生成一个水果盘子，只能装水果
        Plate<Fruit> aPlate = new Plate<Fruit>();
        aPlate.setItem(new Fruit());
        aPlate.setItem(new Apple()); //水果盘子装苹果
        aPlate.setItem(new Banana()); //水果盘子装香蕉
        aPlate.setItem(new GreenApple());//水果盘子装青苹果
        aPlate.setItem(new RedApple());//水果盘子装红苹果
        /*aPlate.setItem(new Meat());
        aPlate.setItem(new Pork());
        aPlate.setItem(new Beef());*/
        // 生成一个水果盘子，只能装苹果
        Plate<? extends Fruit> bPlate = new Plate<Apple>(new RedApple());
        // 上界通配符副作用，不能执行set操作
        /*bPlate.setItem(new Apple());
        bPlate.setItem(new GreenApple());
        bPlate.setItem(new RedApple());*/
        Fruit item = bPlate.getItem();
        // 生成一个水果盘子，只能装香蕉
        Plate<? extends Fruit> cPlate = new Plate<Banana>();
        // 生成一个水果盘子，只能装青苹果
        Plate<? extends Fruit> dPlate = new Plate<GreenApple>();
        // 生成一个水果盘子，只能装红苹果
        Plate<? extends Fruit> ePlate = new Plate<RedApple>();
        // 下届通配符
        Plate<? super Fruit> ap = new Plate<Fruit>();
        ap.setItem(new Fruit());
        ap.setItem(new Apple());
        ap.setItem(new GreenApple());
        ap.setItem(new RedApple());
        ap.setItem(new Banana());
        Object item2 = ap.getItem();
        Banana i = (Banana) ap.getItem();
        Plate<? super Fruit> bp = new Plate<Food>(new Food());
//        bp.setItem(new Food());
        Plate<? super Fruit> cp = new Plate<Food>(new Pork());
//        cp.setItem(new Pork());
        Plate<? super Fruit> dp = new Plate<Food>(new Beef());
//        dp.setItem(new Beef());
        Object item1 = dp.getItem();
    }
}
